/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.meta.service.dictionary.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.je.common.base.DynaBean;
import com.je.common.base.mapper.query.Query;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.util.StringUtil;
import com.je.common.base.util.TreeUtil;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.meta.model.dd.DicInfoVo;
import com.je.meta.service.dictionary.DicTableTreeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service("dicTableTreeService")
public class DicTableTreeServiceImpl implements DicTableTreeService {
    @Autowired
    private BeanService beanService;
    @Autowired
    private MetaService metaService;
    @Autowired
    private CommonService commonService;

    @Override
    public JSONTreeNode buildTableTree(DicInfoVo dicInfoVo) {
        ConditionsWrapper wrapper = ConditionsWrapper.builder().table("V_PRODUCT_MANAGE").eq("PRODUCT_ENABLE_STATE", "1");
        commonService.buildProductWrapper(wrapper, "JE_PRODUCT_MANAGE_ID");
        List<Map<String, Object>> productBeanList = metaService.selectSql(wrapper.apply(" order by PRODUCT_TYPE desc , SY_ORDERINDEX asc"));
        if (productBeanList == null || productBeanList.isEmpty()) {
            return TreeUtil.buildRootNode();
        }
        DynaBean table = beanService.getResourceTable("JE_CORE_RESOURCETABLE");
        List<DynaBean> columns = (List<DynaBean>) table.get(BeanService.KEY_TABLE_COLUMNS);
        JSONTreeNode template = beanService.buildJSONTreeNodeTemplate(columns);
        ConditionsWrapper conditionsWrapper = buildWrapper(dicInfoVo);
        List<DynaBean> tableBeanList = metaService.select("JE_CORE_RESOURCETABLE", conditionsWrapper);
        JSONTreeNode rootNode = TreeUtil.buildRootNode();
        for (Map<String, Object> map : productBeanList) {
            JSONTreeNode eachChildNode = new JSONTreeNode();
            eachChildNode.setId(map.get("SY_PRODUCT_ID").toString() + "_" + dicInfoVo.getFieldCode());
            eachChildNode.setCode(map.get("SY_PRODUCT_CODE").toString());
            eachChildNode.setText(map.get("SY_PRODUCT_NAME").toString());
            eachChildNode.setChecked(false);
            eachChildNode.setDisabled("0");
            eachChildNode.setParent(rootNode.getId());
            eachChildNode.setNodeInfo(dicInfoVo.getFieldCode());
            eachChildNode.setNodeInfoType("product");
            eachChildNode.setExpanded(true);
            eachChildNode.setExpandable(true);
            eachChildNode.setLeaf(true);
            eachChildNode.setBean(map);
            eachChildNode.setIcon(map.get("PRODUCT_ICON") == null ? "fas fa-folder" : map.get("PRODUCT_ICON").toString());
            //eachChildNode.setIconColor("rgb(255, 186, 61)");
            eachChildNode.setLayer("1");
            eachChildNode.setNodePath("ROOT/" + map.get("SY_PRODUCT_ID").toString() + "_" + dicInfoVo.getFieldCode());
            eachChildNode.setNodeType("GENERAL");
            rootNode.getChildren().add(eachChildNode);
        }

        for (JSONTreeNode childNode : rootNode.getChildren()) {
            JSONTreeNode treeNode;
            for (DynaBean eachBean : tableBeanList) {
                if (childNode.getId().equals(eachBean.get("SY_PRODUCT_ID") + "_" + dicInfoVo.getFieldCode()) && "ROOT".equals(eachBean.getStr("SY_PARENT"))) {
                    treeNode = buildTreeNode(dicInfoVo.getFieldCode(), template, childNode.getId(), eachBean, dicInfoVo.getFieldCode());
                    childNode.getChildren().add(treeNode);

                }
            }
            recursiveJsonTreeNode(dicInfoVo.getFieldCode(), template, childNode, tableBeanList, dicInfoVo.getFieldCode());
        }
        return rootNode;
    }

    @Override
    public JSONTreeNode buildDicProject(DicInfoVo dicInfoVo) {
        ConditionsWrapper wrapper = ConditionsWrapper.builder().table("V_PRODUCT_MANAGE").eq("PRODUCT_ENABLE_STATE", "1");
        commonService.buildProductWrapper(wrapper, "JE_PRODUCT_MANAGE_ID");
        List<Map<String, Object>> productBeanList = metaService.selectSql(wrapper.apply(" order by PRODUCT_TYPE desc , SY_ORDERINDEX asc"));
        if (productBeanList == null || productBeanList.isEmpty()) {
            return TreeUtil.buildRootNode();
        }
        JSONTreeNode rootNode = TreeUtil.buildRootNode();
        rootNode.setNodeInfo(dicInfoVo.getFieldCode());
        for (Map<String, Object> map : productBeanList) {
            JSONTreeNode eachChildNode = new JSONTreeNode();
            eachChildNode.setId(map.get("SY_PRODUCT_ID").toString());
            eachChildNode.setCode(map.get("SY_PRODUCT_CODE").toString());
            eachChildNode.setText(map.get("SY_PRODUCT_NAME").toString());
            eachChildNode.setChecked(false);
            eachChildNode.setDisabled("0");
            eachChildNode.setParent(rootNode.getId());
            eachChildNode.setNodeInfo(dicInfoVo.getFieldCode());
            eachChildNode.setNodeInfoType("product");
            eachChildNode.setExpanded(true);
            eachChildNode.setExpandable(true);
            eachChildNode.setLeaf(true);
            eachChildNode.setBean(map);
            eachChildNode.setIcon(map.get("PRODUCT_ICON") == null ? "fas fa-folder" : map.get("PRODUCT_ICON").toString());
            //eachChildNode.setIconColor("rgb(255, 186, 61)");
            eachChildNode.setLayer("1");
            eachChildNode.setNodePath("ROOT/" + map.get("SY_PRODUCT_ID").toString());
            eachChildNode.setNodeType("GENERAL");
            rootNode.getChildren().add(eachChildNode);
        }
        return rootNode;
    }

    private ConditionsWrapper buildWrapper(DicInfoVo dicInfoVo) {
        Query query = new Query();
        if (StringUtil.isNotEmpty(dicInfoVo.getWhereSql())) {
            query.addCustoms(dicInfoVo.getWhereSql());
        }
        if (StringUtil.isNotEmpty(dicInfoVo.getOrderSql())) {
            JSONArray jsonArray = JSON.parseArray(dicInfoVo.getOrderSql());
            if (jsonArray != null && jsonArray.size() > 0) {
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    query.addOrder(jsonObject.getString("code"), jsonObject.getString("type"));
                }
            }
        }
        ConditionsWrapper conditionsWrapper = query.buildWrapper();
        if (StringUtil.isNotEmpty(query.buildOrder())) {
            if (conditionsWrapper.getSql().toUpperCase().contains("ORDER BY")) {
                conditionsWrapper.apply("," + query.buildOrder());
            } else {
                conditionsWrapper.apply(" ORDER BY " + query.buildOrder());
            }
        } else {
            query.addOrder("SY_TREEORDERINDEX", "asc");
            query.addOrder("SY_ORDERINDEX", "asc");
            if (conditionsWrapper.getSql().toUpperCase().contains("ORDER BY")) {
                conditionsWrapper.apply("," + query.buildOrder());
            } else {
                conditionsWrapper.apply(" ORDER BY " + query.buildOrder());
            }
        }
        return conditionsWrapper;
    }

    private void recursiveJsonTreeNode(String nodeInfo, JSONTreeNode template, JSONTreeNode rootNode, List<DynaBean> tableBeanList, String fieldCode) {
        if (tableBeanList == null || tableBeanList.isEmpty()) {
            return;
        }
        JSONTreeNode treeNode;
        for (DynaBean eachBean : tableBeanList) {
            if (rootNode.getId().equals(eachBean.get("SY_PARENT") + "_" + fieldCode)) {
                treeNode = buildTreeNode(nodeInfo, template, rootNode.getId(), eachBean, fieldCode);
                rootNode.getChildren().add(treeNode);
            }
        }

        if (rootNode.getChildren() == null || rootNode.getChildren().isEmpty()) {
            rootNode.setLeaf(true);
            return;
        }

        rootNode.setLeaf(false);
        for (JSONTreeNode treeNodeChild : rootNode.getChildren()) {
            recursiveJsonTreeNode(nodeInfo, template, treeNodeChild, tableBeanList, fieldCode);
        }
    }

    private JSONTreeNode buildTreeNode(String nodeInfo, JSONTreeNode template, String parentNodeId, DynaBean bean, String fieldCode) {
        JSONTreeNode node = new JSONTreeNode();
        node.setId(bean.get("JE_CORE_RESOURCETABLE_ID").toString() + "_" + fieldCode);
        node.setParent(parentNodeId);
        node.setLeaf(true);
        if (StringUtil.isNotEmpty(template.getText())) {
            node.setText(getString(bean.get(template.getText())));
        }
        if (StringUtil.isNotEmpty(template.getCode())) {
            node.setCode(getString(bean.get(template.getCode())));
        }
        //节点信息
        node.setNodeInfo(getString(bean.get("RESOURCETABLE_TYPE")));

        //节点信息类型
        if (StringUtil.isNotEmpty(template.getNodeInfoType())) {
            node.setNodeInfoType(getString(template.getNodeInfoType()));
        }
        //节点类型
        if (StringUtil.isNotEmpty(template.getNodeType())) {
            node.setNodeType(getString(bean.get(template.getNodeType())));
        }
        //节点路径
        if (StringUtil.isNotEmpty(template.getNodePath())) {
            node.setNodePath(getString(bean.get(template.getNodePath())) + "/" + "_" + fieldCode);
        }
        //是否禁用
        if (StringUtil.isNotEmpty(template.getDisabled())) {
            node.setDisabled(getString(bean.get(template.getDisabled())));
        }
        //树形排序
        if (StringUtil.isNotEmpty(template.getTreeOrderIndex())) {
            node.setTreeOrderIndex(getString(bean.get(template.getTreeOrderIndex())));
        }
        //图标样式
        if (StringUtil.isNotEmpty(template.getIcon())) {
            if ("GENERAL".equals(node.getNodeType())) {
                node.setIcon("fas fa-folder");
                node.setIconColor("rgb(255, 186, 61)");
            } else {
                node.setIcon(bean.getStr(template.getIcon()));
            }
        }

        //是否禁用
        if (StringUtil.isNotEmpty(template.getDisabled())) {
            node.setDisabled(getString(bean.get(template.getDisabled())));
        } else {
            node.setDisabled("0");
        }
        //描述
        if (StringUtil.isNotEmpty(template.getDescription())) {
            node.setDescription(getString(bean.get(template.getDescription())));
        }
        //排序
        if (StringUtil.isNotEmpty(template.getOrderIndex())) {
            node.setOrderIndex(bean.get(template.getOrderIndex()) + "");
        }
        //node.setNodeType("GENERAL");
        node.setBean(bean.getValues());
        return node;
    }

    private String getString(Object obj) {
        if (obj == null) {
            return null;
        }
        return obj.toString();
    }

}
